package versi.vitro.oaiserviceprovider.helper;

import java.net.MalformedURLException;
import java.net.URL;

import org.jmock.Mockery;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import versi.vitro.oaiserviceprovider.service.handle.helper.HandleHelper;
import versi.vitro.oaiserviceprovider.service.handle.helper.HandleHelperImpl;

public class HandleHelperImplTest {

    private Mockery context;

    @BeforeMethod
    public void setUp() {
	context = new Mockery();
    }

    @Test
    public void testPidCreateHandleCreateURL() throws MalformedURLException {

	final String resourceType = "url";
	final String resourceValue = "dummyResourceValue";

	final URL serviceURL = new URL("https://dummy.org/pids/mint?type=URL&value=dummyResourceValue");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handle = hs.pidCreateHandle(resourceType, resourceValue);

	Assert.assertEquals("10000.0/0001", handle);

	context.assertIsSatisfied();

    }

    @Test
    public void testPidCreateHandleCreateURLWhenResourceTypeIsDESC() throws MalformedURLException {

	final String resourceType = "DESC";
	final String resourceValue = "dummyResourceValue";

	final URL serviceURL = new URL("https://dummy.org/pids/mint?type=DESC&value=dummyResourceValue");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }

	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handle = hs.pidCreateHandle(resourceType, resourceValue);

	Assert.assertEquals("10000.0/0001", handle);
	context.assertIsSatisfied();

    }

    @Test
    public void testPidCreateHandleCreateURLWithIndex() throws MalformedURLException {

	final String resourceType = "url";
	final String resourceValue = "dummyResourceValue";

	final int index = 1;
	final URL serviceURL = new URL("https://dummy.org/pids/mint?type=URL&value=dummyResourceValue&index=1");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handle = hs.pidCreateHandle(resourceType, resourceValue, index);

	Assert.assertEquals("10000.0/0001", handle);

	context.assertIsSatisfied();

    }

    @Test
    public void testPidCreateHandleCreateURLWithIndexWhenResourceTypeIsDESC() throws MalformedURLException {

	final String resourceType = "desc";
	final String resourceValue = "dummyResourceValue";

	final int index = 1;
	final URL serviceURL = new URL("https://dummy.org/pids/mint?type=DESC&value=dummyResourceValue&index=1");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handle = hs.pidCreateHandle(resourceType, resourceValue, index);

	Assert.assertEquals("10000.0/0001", handle);

	context.assertIsSatisfied();

    }

    @Test(expectedExceptions = RuntimeException.class)
    public void testPidCreateHandleWillThrowExceptionForInvalidResourceType() throws MalformedURLException {

	final String resourceType = "wrongType";
	final String resourceValue = "dummyResourceValue";

	final int index = 1;
	final URL serviceURL = new URL("https://dummy.org/pids/mint?type=DESC&value=dummyResourceValue&index=1");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handle = hs.pidCreateHandle(resourceType, resourceValue, index);

	Assert.assertEquals("10000.0/0001", handle);

	context.assertIsSatisfied();

    }

    @Test
    public void testPidAddValue() throws MalformedURLException {

	final String handle = "10000.0/0001";
	final String resourceType = "url";
	final String resourceValue = "dummyResourceValue";

	final URL serviceURL = new URL(
		"https://dummy.org/pids/addValue?type=URL&value=dummyResourceValue&handle=10000.0/0001");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handleResult = hs.pidAddValue(handle, resourceType, resourceValue);

	Assert.assertEquals("10000.0/0001", handleResult);

	context.assertIsSatisfied();

    }

    @Test
    public void testPidAddValueWithIndex() throws MalformedURLException {

	final String handle = "10000.0/0001";
	final String resourceType = "url";
	final String resourceValue = "dummyResourceValue";
	final int index = 1;

	final URL serviceURL = new URL(
		"https://dummy.org/pids/addValueByIndex?type=URL&value=dummyResourceValue&index=1&handle=10000.0/0001");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	String handleResult = hs.pidAddValue(handle, resourceType, resourceValue, index);

	Assert.assertEquals("10000.0/0001", handleResult);

	context.assertIsSatisfied();

    }

    @Test
    public void testPidDeleteValueByIndex() throws MalformedURLException {

	final String handle = "10000.0/0001";
	final int index = 1;

	final URL serviceURL = new URL("https://dummy.org/pids/deleteValueByIndex?handle=10000.0/0001&index=1");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	boolean handleResult = hs.pidDeleteValueByIndex(handle, index);

	Assert.assertEquals(true, handleResult);

	context.assertIsSatisfied();

    }

    @Test
    public void testPidModifyHandle() throws MalformedURLException {

	final String handle = "10000.0/0001";
	final int index = 1;
	final String resourceValue = "dummyResourceValue";

	final URL serviceURL = new URL(
		"https://dummy.org/pids/modifyValueByIndex?handle=10000.0/0001&index=1&value=dummyResourceValue");

	HandleHelper hs = new HandleHelperImpl() {
	    protected void establishANDScommunication() {

	    }

	    protected String sendCommand(URL url, String params) {

		assert url.equals(serviceURL);
		return "dummy response";

	    }

	    public String extractHandleFromResponse(String response) {

		return "10000.0/0001";

	    }
	};

	hs.setAndServiceURL("https://dummy.org/pids");

	boolean handleResult = hs.pidModifyHandle(handle, index, resourceValue);

	Assert.assertEquals(true, handleResult);

	context.assertIsSatisfied();

    }

}
